package com.adhere.auth.service.impl;

import com.adhere.auth.config.JwtProperties;
import com.adhere.auth.pojo.LoginUser;
import com.adhere.auth.pojo.RbacUser;
import com.adhere.auth.service.TokenService;
import com.adhere.auth.utils.IpUtils;
import com.adhere.auth.utils.ServletUtils;
import com.adhere.common.constants.SecurityConstants;
import com.adhere.common.constants.RedisConstants;
import com.adhere.common.utils.JwtUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author WT
 * @date 2022/02/07 16:13:18
 */
@Service
public class TokenServiceImpl implements TokenService {

    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;
    private final JwtProperties jwtProperties;

    public TokenServiceImpl (RedisTemplate<String, Object> redisTemplate,
                             ObjectMapper objectMapper,
                             JwtProperties jwtProperties) {
        this.redisTemplate = redisTemplate;
        this.objectMapper = objectMapper;
        this.jwtProperties = jwtProperties;
    }

    @Override
    public Map<String, String> createToken(LoginUser loginUser) {

        Long expiration = jwtProperties.getExpiration();

        // == 取出 rbacUser 中的数据填充到 loginUser 中 ==
        RbacUser rbacUser = loginUser.getRbacUser();
        Long userId = rbacUser.getId();
        String loginName = rbacUser.getLoginName();
        loginUser.setUserId(userId);
        loginUser.setLoginName(loginName);
        loginUser.setIpaddr(IpUtils.getIpAddress(ServletUtils.getRequest()));
        // 设置用户登录时间
        loginUser.setLoginTime(System.currentTimeMillis());
        // 设置用户过期时间
        loginUser.setExpireTime(loginUser.getLoginTime() + expiration * 1000);
        // 拼接缓存 key 为：
        String userKey = RedisConstants.LOGIN_USER_KEY + userId;
        try {
            String loginUserJson = objectMapper.writeValueAsString(loginUser);
            redisTemplate.opsForValue().set(userKey, loginUserJson, expiration, TimeUnit.SECONDS);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // Jwt 存储信息
        Map<String, Object> claimsMap = new HashMap<>();
        claimsMap.put(SecurityConstants.USER_KEY, userKey);
        claimsMap.put(SecurityConstants.USER_ID, userId);
        claimsMap.put(SecurityConstants.LOGIN_NAME, loginName);

        // 接口返回信息
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("access_token", JwtUtils.generateToken(claimsMap, expiration, jwtProperties.getSecret()));
        return resultMap;
    }

}
